package wiki.kaizen.cloud.security.session.support;

import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.session.ExpiredSessionException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import wiki.kaizen.cloud.security.session.support.listener.SessionValidateListener;

import java.util.Collection;
import java.util.List;

@Slf4j
public class KaizenSessionManager extends DefaultWebSessionManager {

    @Setter
    private List<SessionValidateListener> validates;

    @Override
    public void validateSessions() {
        if (log.isInfoEnabled()) {
            log.info("开始校验Session有效性...");
        }

        int invalidCount = 0;

        Collection<Session> activeSessions = getActiveSessions();
        boolean isValidate = validates != null && validates.size() > 0;
        if (activeSessions != null && !activeSessions.isEmpty()) {
            for (Session session : activeSessions) {
                try {
                    //simulate a lookup key to satisfy the method signature.
                    //this could probably stand to be cleaned up in future versions:
                    SessionKey key = new DefaultSessionKey(session.getId());
                    validate(session, key);

                    if (isValidate){ //通过校验
                        validates.forEach(
                            validate->validate.success(session)
                        );
                    }
                } catch (InvalidSessionException e) {//进入异常未通过校验
                    if (log.isDebugEnabled()) {
                        boolean expired = (e instanceof ExpiredSessionException);
                        String msg = "Session[" + session.getId() + "]" + (expired ? " (已过期)" : " (已停止)");
                        log.debug(msg);
                    }
                    if (isValidate){
                        validates.forEach(
                            validate->validate.fail(session)
                        );
                    }
                    invalidCount++;

                }
            }
        }

        if (log.isInfoEnabled()) {
            String msg = "Session校验已完成.";
            if (invalidCount > 0) {
                msg += "  [" + invalidCount + "] 条Session已被停止.";
            }
            log.info(msg);
        }
    }
}
